﻿using System;
using System.Collections.Generic;
using System.Text;


namespace KNXObjects.Addresses
{
    public class PhysicalAddress : IEquatable<PhysicalAddress>
    {
        #region Fields
        private ushort m_ZoneNumber;
        private ushort m_LineNumber;
        private ushort m_DeviceNumber;
        private ushort m_Value = 0;



        #endregion

        #region Properties

        public ushort ZoneNumber
        {
            get { return m_ZoneNumber; }
            set { m_ZoneNumber = value; }
        }

        public ushort LineNumber
        {
            get { return m_LineNumber; }
            set { m_LineNumber = value; }
        }

        public ushort DeviceNumber
        {
            get { return m_DeviceNumber; }
            set { m_DeviceNumber = value; }
        }
        public ushort Value
        {
            get {
                if (m_Value == 0)
                    m_Value = Convert.ToUInt16( ((ZoneNumber & 0x0f) << 12) | ((LineNumber & 0x0f) << 8) | (DeviceNumber & 0xff) );
                return m_Value; 
            }            
        }
        #endregion

        #region Constructors
        public PhysicalAddress(string readableAddress)
        {
            ExtractInfo(readableAddress);
        }

        public PhysicalAddress(ushort binaryAddress)
        {
            ExtractInfo(binaryAddress);
            m_Value = binaryAddress;
        }


        #endregion

        #region Methods

        private void ExtractInfo(string readableAddress)
        {
            string[] parts = readableAddress.Split('.');
            if (parts.Length == 3)
            {
                ZoneNumber = Convert.ToUInt16(parts[0]);
                LineNumber = Convert.ToUInt16(parts[1]);
                DeviceNumber = Convert.ToUInt16(parts[2]);
            }
        }

        private void ExtractInfo(ushort binaryAddress)
        {
            ZoneNumber = Convert.ToUInt16((binaryAddress >> 12) & 0x0f);
            LineNumber = Convert.ToUInt16((binaryAddress >> 8) & 0x0f);
            DeviceNumber = Convert.ToUInt16(binaryAddress & 0xff);

        }
        public override string ToString()
        {
            return string.Format("{0}.{1}.{2}", ZoneNumber, LineNumber, DeviceNumber);
        }
        #endregion

        #region IEquatable<PhysicalAddress> Members

        public bool Equals(PhysicalAddress other)
        {
            return Value.Equals(other.Value);
        }

        #endregion
    }
}
